<template>
  <div class="socket-test-container">
    <h2 class="title">Socket 连接测试</h2>

    <!-- 连接状态 -->
    <div class="status-wrapper">
      <van-tag :type="isConnected ? 'success' : 'danger'" size="large">
        {{ isConnected ? '✅ 已连接' : '❌ 未连接' }}
      </van-tag>
      <van-tag v-if="isConnecting" type="warning" size="large">⏳ 连接中...</van-tag>
      <van-tag v-if="hasError" type="danger" size="large">⚠️ 连接错误</van-tag>
    </div>

    <!-- 连接按钮 -->
    <div class="button-wrapper">
      <van-button 
        type="primary" 
        size="large" 
        @click="connect"
        :disabled="isConnected || isConnecting"
      >
        连接
      </van-button>
      <van-button 
        type="danger" 
        size="large" 
        @click="disconnect"
        :disabled="!isConnected"
      >
        断开
      </van-button>
    </div>

    <!-- 消息发送 -->
    <div class="message-input">
      <van-field 
        v-model="message" 
        label="消息内容"
        placeholder="输入要发送的消息" 
        :disabled="!isConnected"
      >
        <template #button>
          <van-button 
            size="small" 
            type="primary" 
            @click="sendMessage"
            :disabled="!isConnected || !message"
          >
            发送
          </van-button>
        </template>
      </van-field>
    </div>

    <!-- 消息记录 -->
    <div class="logs-wrapper">
      <h3>消息日志</h3>
      <div class="logs-container">
        <div 
          v-for="(log, index) in logs" 
          :key="index" 
          class="log-item"
          :class="'log-' + log.type"
        >
          <span class="log-time">{{ log.time }}</span>
          <span class="log-type">{{ log.type }}</span>
          <span class="log-message">{{ log.message }}</span>
        </div>
      </div>
    </div>

    <div class="socket-info" v-if="tradeNo || socketId">
      <div v-if="tradeNo" class="info-item">
        <span class="info-label">订单号 (Trade No):</span>
        <span class="info-value">{{ tradeNo }}</span>
      </div>
      <div v-if="socketId" class="info-item">
        <span class="info-label">用户ID (Socket ID):</span>
        <span class="info-value">{{ socketId }}</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import { socketInstance } from '@/utils/socket'
import { showToast } from 'vant'

// 状态和变量
const socket = socketInstance
const message = ref('')
const logs = ref([])
const tradeNo = ref('')
const socketId = ref('') // Socket ID

// 本地响应式状态（用于UI显示）
const isConnected = ref(false)
const isConnecting = ref(false)
const hasError = ref(false)

// 事件监听清理函数
let systemHandler = null
let connectHandler = null
let disconnectHandler = null
let connectErrorHandler = null
let stateWatcher = null

// 从URL参数获取trade_no
const getTradeNo = () => {
  const urlParams = new URLSearchParams(window.location.search)
  return urlParams.get('trade_no') || ''
}

// 添加日志
const addLog = (type, message) => {
  const time = new Date().toLocaleTimeString()
  logs.value.unshift({ type, message, time })
  
  // 限制日志数量
  if (logs.value.length > 50) {
    logs.value = logs.value.slice(0, 50)
  }
}

// 连接
const connect = () => {
  if (isConnected.value || isConnecting.value) {
    return
  }
  
  isConnecting.value = true
  hasError.value = false
  socket.connect()
  addLog('info', '正在连接...')
}

// 断开
const disconnect = () => {
  if (!isConnected.value) {
    return
  }
  
  socket.disconnect()
  addLog('info', '正在断开连接...')
}

// 发送消息
const sendMessage = () => {
  if (!message.value.trim()) {
    showToast('消息内容不能为空')
    return
  }
  
  if (!isConnected.value) {
    showToast('请先连接Socket')
    return
  }
  
  // 按照原始逻辑发送消息，携带content字段
  const success = socket.emit('message', { content: message.value })
  if (success) {
    addLog('send', `🧑 我：${message.value}`)
    message.value = ''
    showToast('消息已发送')
  } else {
    addLog('error', '发送失败，可能未连接')
    showToast('发送失败')
  }
}

// 处理连接成功
const handleConnect = () => {
  // 更新状态
  isConnected.value = true
  isConnecting.value = false
  hasError.value = false
  
  // 更新 socketId
  socketId.value = socket.getSocketId()
  
  addLog('system', `✅ 已连接，Socket ID: ${socketId.value}`)
  showToast('连接成功')
  
  // 连接成功后自动注册用户（携带trade_no）
  if (tradeNo.value) {
    socket.emit('register', { trade_no: tradeNo.value })
    addLog('info', `已注册用户，trade_no: ${tradeNo.value}`)
  } else {
    addLog('warning', '未提供trade_no参数')
  }
}

// 处理断开连接
const handleDisconnect = (reason) => {
  // 更新状态
  isConnected.value = false
  isConnecting.value = false
  
  // 清空 socketId
  socketId.value = ''
  
  const reasonText = reason ? ` (原因: ${reason})` : ''
  addLog('system', `❌ 连接断开${reasonText}`)
  showToast('连接已断开')
}

// 处理连接错误
const handleConnectError = (error) => {
  isConnected.value = false
  isConnecting.value = false
  hasError.value = true
  
  console.error('连接错误:', error)
  addLog('error', `连接错误: ${error.message || error}`)
  showToast('连接失败')
}

// 处理系统消息
const handleSystemMessage = (data) => {
  console.log('收到管理端消息:', data)
  addLog('receive', `📢 管理端消息：${typeof data === 'object' ? JSON.stringify(data) : data}`)
  
  // 显示Toast提醒
  showToast({
    message: typeof data === 'object' ? (data.message || JSON.stringify(data)) : data,
    duration: 3000
  })
}

// 监听Socket状态变化（仅用于同步底层socket状态）
const watchSocketState = () => {
  // 创建一个计时器来同步socket底层状态
  const interval = setInterval(() => {
    // 同步底层连接状态到本地状态（用于双保险）
    const actualConnected = socket.connected.value
    if (actualConnected !== isConnected.value) {
      console.log('[状态同步] 检测到状态不一致，actualConnected:', actualConnected, 'isConnected:', isConnected.value)
      // 这里只记录，不主动修改，避免状态冲突
    }
  }, 1000)

  return interval
}

onMounted(() => {
  // 获取URL参数中的trade_no
  tradeNo.value = getTradeNo()
  
  addLog('info', '组件已挂载')
  if (tradeNo.value) {
    addLog('info', `获取到 trade_no: ${tradeNo.value}`)
  } else {
    addLog('warning', '未检测到 trade_no 参数')
  }

  // 设置事件监听器
  connectHandler = socket.on('connect', handleConnect)
  disconnectHandler = socket.on('disconnect', handleDisconnect)
  connectErrorHandler = socket.on('connect_error', handleConnectError)
  systemHandler = socket.on('system', handleSystemMessage)

  // 开始状态监听
  stateWatcher = watchSocketState()
  
  // 延迟100ms后自动连接，确保所有监听器都已注册
  setTimeout(() => {
    addLog('info', '开始自动连接...')
    connect()
  }, 100)
})

onBeforeUnmount(() => {
  addLog('info', '组件即将卸载')
  
  // 清理所有监听器
  if (connectHandler) socket.off('connect', connectHandler)
  if (disconnectHandler) socket.off('disconnect', disconnectHandler)
  if (connectErrorHandler) socket.off('connect_error', connectErrorHandler)
  if (systemHandler) socket.off('system', systemHandler)
  
  // 清理状态监听器
  if (stateWatcher) {
    clearInterval(stateWatcher)
  }

  // 注意：这里不要断开连接，因为是全局单例
  // socket.disconnect()
})
</script>

<style scoped>
.socket-test-container {
  padding: 16px;
  max-width: 800px;
  margin: 0 auto;
}

.title {
  margin-bottom: 24px;
  text-align: center;
}

.status-wrapper {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

.button-wrapper {
  display: flex;
  gap: 12px;
  margin-bottom: 24px;
}

.message-input {
  margin-bottom: 24px;
}

.logs-wrapper {
  margin-top: 16px;
}

.logs-container {
  height: 300px;
  overflow-y: auto;
  border: 1px solid #ebedf0;
  border-radius: 8px;
  padding: 8px;
}

.log-item {
  padding: 6px 8px;
  margin-bottom: 8px;
  border-radius: 4px;
  font-size: 14px;
  display: flex;
}

.log-time {
  color: #969799;
  width: 80px;
  flex-shrink: 0;
}

.log-type {
  width: 60px;
  margin-right: 8px;
  flex-shrink: 0;
  text-align: center;
  font-weight: 600;
}

.log-message {
  flex-grow: 1;
  word-break: break-all;
}

.log-system {
  background-color: #fef9e7;
}

.log-info {
  background-color: #f7f8fa;
}

.log-send {
  background-color: #e8f4ff;
}

.log-receive {
  background-color: #e8fff4;
}

.log-error {
  background-color: #fff2f0;
}

.socket-info {
  margin-top: 16px;
  padding: 12px;
  background-color: #f7f8fa;
  border-radius: 8px;
}

.info-item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 14px;
}

.info-item:last-child {
  margin-bottom: 0;
}

.info-label {
  color: #646566;
  font-weight: 600;
}

.info-value {
  color: #323233;
  word-break: break-all;
}
</style>
